package ausgabeUndDatenverwaltung;

import java.util.*;

import einlesenUndDatenverwaltung.Buchung;
import einlesenUndDatenverwaltung.Kurs;
import einlesenUndDatenverwaltung.KursListe;
import einlesenUndDatenverwaltung.Student;

/**
 * Bildet die Containerklasse für die einzelnen Platzkarten je Teilnehmer,
 * Prüfungstag und Universitaet (Erstellung flexibler Verwaltungslisten-Objekte
 * z.B. eine Liste je Universitaet mit den entsprechenden Platzkarten).
 * Verwendet zur Bildung der Listen Platzkarten.
 * 
 * @author (Max Bogner)
 * @version (14.01.2014)
 */
public class PlatzKartenListe {

	// Liste fuer alle Platzkarten Objekte, beinhaltet platzkarten
	private Vector<PlatzKarte> platzkartenliste = new Vector<PlatzKarte>();

	/**
	 * 
	 * Konstruktor fuer Objekte der Klasse PlatzKartenListe
	 * 
	 * @author Max Bogner
	 */

	public PlatzKartenListe() {

	}

	/**
	 * Gibt die platzkartenliste zurueck
	 * 
	 * @author Max Bogner
	 * @return platzkartenliste
	 */
	public Vector<PlatzKarte> getPlatzkartenliste() {
		return platzkartenliste;
	}

	/**
	 * setzt die platzkartenliste
	 * 
	 * @author Max Bogner
	 * @param platzkartenliste
	 *            : Platzkartenliste die gesetzt werden soll
	 */
	public void setPlatzkartenliste(Vector<PlatzKarte> platzkartenliste) {
		this.platzkartenliste = platzkartenliste;
	}

	/**
	 * sortiert die platzkartenliste absteigend nach der Anzahl, der gebuchten
	 * Kurse
	 * 
	 * @author Max Bogner
	 */
	public void getPlatzKartenListeSortedByAnzahlKurs() {
		int anzahlKurseAlt = -99;
		List list = platzkartenliste;
		Collections.sort(list, PlatzKarte.AnzahlKurseAbsteigend);
		platzkartenliste = (Vector<PlatzKarte>) list;

	}

	/**
	 * Setzt den uebergebenen Pruefungstag fuer alle platzkarten der
	 * platzkartenliste
	 * 
	 * @author Max Bogner
	 * @param pt
	 *            : Pruefungstag der fuer alle objekte in der platzkartenliste
	 *            gesetzt werden soll
	 * 
	 */

	public void setPruefungstagForAllPlatzkarten(PruefungsTag pt) {
		for (int i = 0; i < platzkartenliste.size(); i++) {
			platzkartenliste.elementAt(i).setPruefungstag(pt);
		}

	}

	// wird benoetigt
	/**
	 * Ermittelt ob ein Student mehr als in_i Kurse an einem Tag gebucht hat
	 * 
	 * @author Max Bogner
	 * @param in_i
	 *            Anzahl der Kurse zum ueberpruefen
	 * @return true, wenn ein Student mehr als in_i Kurse belegt hat; false wenn
	 *         kein Student mehr als in_i Kurse hat
	 */
	public boolean einStudentHatMehrKurseProTagAls(int in_i) {
		Boolean ret = false;
		for (int i = 0; i < platzkartenliste.size(); i++) {

			if (platzkartenliste.elementAt(i).getKursliste().getKursliste()
					.size() > in_i) {
				ret = true;
			}

		}
		return ret;

	}

	/**
	 * Fügt der Liste ein Element hinzu.
	 * 
	 * Gibt einen Boolean als Statusmeldung zurück.
	 * 
	 * @param anwesenheit
	 *            Eintrag der der Liste hinzugefügt werden soll
	 * @return Status ob der Eintrag erfolgreich hinzugefügt werden konnte
	 */
	// wird benoetigt
	public boolean addElement(PlatzKarte pk) {
		try {
			platzkartenliste.add(pk);
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Löscht das uebergebene Element aus der Liste.
	 * 
	 * Gibt einen Boolean als Statusmeldung zurück.
	 * 
	 * @param buchung
	 *            Eintrag der aus der Liste entfernt werden soll
	 * @return Status ob der Eintrag erfolgreich gelöscht wurde
	 */
	// wird benoetigt
	public boolean removeElement(PlatzKarte pk) {
		try {
			platzkartenliste.remove(pk);
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	// wird benoetigt
	/**
	 * Ermittelt den Kurs, der am haeufigsten gebucht wurde
	 * 
	 * @author Max Bogner
	 * @param pkl
	 *            Platzkartenliste von der der Kurse mit den meisten Buchungen
	 *            ermittelt werden soll
	 * @param klUnique
	 *            Einzigartige Kursliste
	 * @return Kurs der in der uebergebenen Platzkartenliste am haeufigsten
	 *         gebucht wurde
	 */
	public Kurs getKursMitAmMeistenStudenten(PlatzKartenListe pkl,
			KursListe klUnique) {
		KursListe kl = new KursListe();
		// erstellt eine kursliste mit allen Kursen ueber alle Platzkarten
		for (int i = 0; i < pkl.getPlatzkartenliste().size(); i++) {

			kl.addKursListeToKursListe(pkl.getPlatzkartenliste().elementAt(i)
					.getKursliste());

		}

		// Sortiert die Kursliste
		List list = kl.getKursliste();
		Kurs.setSortierKriterium("kursid");
		Collections.sort(list, Kurs.KursIDsAbsteigend);
		kl.setKursliste((Vector<Kurs>) list);

		int AnzahlKurse = 1;
		int Zaehler = 1;
		for (int i = 0; i < kl.getKursliste().size(); i++) {

			if (i != 0) {
				Boolean Hinzufuegen = true;
				// Solange Element mit naechstem Element gleich ist zaehle hoch
				if (kl.getKursliste().elementAt(i).getKursid() == kl
						.getKursliste().elementAt(i - 1).getKursid()) {
					// zaehlt die Buchungen pro Kurs
					Zaehler = Zaehler + 1;
					Hinzufuegen = false;

				}

				if (Hinzufuegen) {

					int kursid = kl.getKursliste().elementAt(i - 1).getKursid();
					// set die Anzahl, der Buchungen pro Kurs in der
					// einzigartigen Kursliste
					klUnique.getKursImproved(kursid)
							.setAnzahlBuchungen(Zaehler);
					Zaehler = 1;

				}
			}

		}
		// Die Kursliste wird absteigend nach der Anzahl der Buchungen sortiert
		List lUnique = klUnique.getKursliste();
		Kurs.setSortierKriterium("AnzahlBuchungen");
		Collections.sort(lUnique, Kurs.AnzahlBuchungenAbsteigend);
		klUnique.setKursliste((Vector<Kurs>) lUnique);

		// Der erste Kurs der sortierten Kursliste wird uebergeben
		return klUnique.getKursliste().get(0);

	}



	/**
	 * Erstellt aus der Platzkartenliste eine Liste mit Platzkartenlisten pro Tag.
	 * Anforderung an die platzkartenliste: Diese muss nach Tagen sortiert sein
	 * @author Max Bogner
	 * @return Platzkartenliste mit einer Platzkartenliste fuer jeden Pruefungstag
	 */
	public Vector<PlatzKartenListe> createPlatzKartenListenProTag() {
		
		PlatzKartenListe pkl = new PlatzKartenListe();
		//Ausgabeliste mit Platzkartenlisten
		Vector<PlatzKartenListe> pkll = new Vector<PlatzKartenListe>();
		pkl.addElement(platzkartenliste.elementAt(0));
		// int endinit = 0;
		
		for (int i = 0; i < platzkartenliste.size() - 1; i++) {
			//Pruefungstag fuer i-ten Durchlauf
			String strPt1 = platzkartenliste.elementAt(i).getPruefungstag()
					.getName();
			//Pruefungstag fuer i+1-ten Durchlauf
			String strPt2 = platzkartenliste.elementAt(i + 1).getPruefungstag()
					.getName();
			//Vergleich ob die beiden Pruefungstage gleich sind
			if (strPt1 == strPt2) {
				//
				pkl.addElement(platzkartenliste.elementAt(i + 1));
				System.out.println("Add to liste fuer tag "
						+ platzkartenliste.elementAt(i + 1));
			} else {
				System.out.println("erstelle neue Liste: tag "
						+ platzkartenliste.elementAt(i + 1));
				//hinzufuegen der Platzkartenliste zur Liste mit Platzkartenliste je Pruefungstag
				pkll.add(pkl);
				//Neue Platzkartenliste erstellen
				pkl = new PlatzKartenListe();
				//Platzkartenliste mit dem ersten Element fuellen
				pkl.addElement(platzkartenliste.elementAt(i + 1));
			}
		}
		//hinzufuegen der Platzkartenliste zur Liste mit Platzkartenliste je Pruefungstag
		pkll.add(pkl);
		System.out.println("Vector size " + pkll.size());
		//uebergeben der Platzkartenliste mit Platzkartenlisten fuer jeden Tag
		return pkll;

	}

	// wird verwendet
	/**
	 * Erstellt eine Platzkartenliste mit allen Platzkarten, die mehr als
	 * maxKurse Kurse haben
	 * 
	 * @param maxKurse
	 *            Grenzwert: Legt fest ab welcher Kurslistengroesse die
	 *            Platzkarten in die neue Liste uebernommen werden
	 * @author Max Bogner           
	 * @return Platzkartenliste mit Platzkarten, die alle mehr als maxKurse
	 *         Kurse in der Kursliste haben
	 */
	public PlatzKartenListe getPlatzKartenMitMehrKursenAls(int maxKurse) {
		// Platzkartenliste, die alle Platzkarten mit mehr als <maxKurse>
		// speichert
		PlatzKartenListe pklMehrAlsDreiKurse = new PlatzKartenListe();
		for (int i = 0; i < platzkartenliste.size(); i++) {
			// schaut ob die Kurslistengroesse hoeher ist als die Variable
			// <maxKurse>
			if (platzkartenliste.elementAt(i).getKursliste().getKursliste()
					.size() > maxKurse) {
				pklMehrAlsDreiKurse.addElement(platzkartenliste.elementAt(i));

				// if (platzkartenliste.get(i).getKursliste().getKursliste()
				// .size() > maxKurse) {
				// pklMehrAlsDreiKurse.addElement(platzkartenliste.get(i));
				//
				// }

			}
		}
		// gibt die erstellte Platzkartenliste zurueck
		return pklMehrAlsDreiKurse;
	}

	// }
	/**
	 * 
	 * Gibt die Platzkartenliste passend fuer die Ausgabe im Filesystem aus. Die
	 * String der PlatzKartenListe wird aufgeteilt nach Universitaet und ist
	 * sortiert nach pruefungstag
	 * 
	 * @author Max Bogner
	 * @return String passend fuer die Ausgabe der PlatzKartenListe
	 * @see java.lang.Object#toString()
	 **/
	// wird verwendet
	public String toString() {
		// Liste mit Platzkartenlisten
		Vector<PlatzKartenListe> pkll = new Vector<PlatzKartenListe>();
		pkll = this.PlatzkartenlisteNachUni();
		String str = "";
		// geht die Liste mit Platzkartenlisten durch--> fuer jede Uni befindet
		// sich ein Eintrag in der Liste
		for (int pkli = 0; pkli < pkll.size(); pkli++) {
			PlatzKartenListe cpkl = new PlatzKartenListe();
			cpkl = pkll.elementAt(pkli);
			boolean init = true;
			for (int i = 0; i < cpkl.getPlatzkartenliste().size() - 1; i++) {
				// Die Universitaet soll vor jeder Platzkartenliste geschrieben
				// werden
				if (init) {
					str = str
							+ "Universitaet: "
							+ cpkl.getPlatzkartenliste().elementAt(i)
									.getStudent().getUniversitaet() + "\n";
					init = false;
				}
				// ermitteln von Daten, die fuer den Ausgabestring benoetigt
				// werden
				int platzkartennummer = i + 1;
				Student st = cpkl.getPlatzkartenliste().elementAt(i)
						.getStudent();
				PruefungsTag tag = cpkl.getPlatzkartenliste().elementAt(i)
						.getPruefungstag();
				KursListe kurse = cpkl.getPlatzkartenliste().elementAt(i)
						.getKursliste();

				// Zusammenbau des Ausgabestrings
				str = str + "\n" + "Platzkarte " + platzkartennummer + "\n"
						+ "VAWi - Pruefung in " + st.getUniversitaet() + " - "
						+ tag.getName() + "\n" + "Teilnehmer: " + st.getName()
						+ "," + st.getVorname() + "\n" + "Heutige Kurse: "
						+ "\n" + kurse.toString() + "\n";

			}
		}
		return str;
	}

	// wird verwendet
	/**
	 * Löscht Platzkarten aus der Platzkartenliste anhand des uebergebenen
	 * Kurses <k>
	 * 
	 * @author Max Bogner
	 * @param k
	 *            Kriterium fuer die Loeschung der Platzkarte
	 * @return Platzkartenliste ohne Platzkarten die den Kurs <k> enthielten
	 */
	public PlatzKartenListe removePlatzKarteByKurs(Kurs k) {

		PlatzKartenListe pklRemoved = new PlatzKartenListe();
		pklRemoved.getPlatzkartenliste().removeAllElements();
		Boolean removed = false;
		// platzkarten druchgehen
		for (int i = 0; i < platzkartenliste.size(); i++) {
			KursListe kl = new KursListe();
			kl = platzkartenliste.elementAt(i).getKursliste();
			// ueberpruefen ob Eintraege in der Kursliste vorhanden sind
			if (kl.getKursliste().size() > 0) {
				// Durchgehen der kurslisten der platzkarten
				for (int z = 0; z < kl.getKursliste().size(); z++)
					// Kurs ku = new Kurs();
					if (k.getKursid() == kl.getKursliste().elementAt(z)
							.getKursid()) {
						// Kurs wird aus der Kursliste der Platzkarte entfernt
						kl.getKursliste().removeElementAt(z);
						// Kurs wurde geloescht
						removed = true;
					}
				// Der Kurs dieses For-Schleifen Durchlaufs wurde entfernt
				if (removed) {
					// Anlegen einer neuen Plaztkarte
					PlatzKarte pkNew = new PlatzKarte();
					// Anlegen einer neuer Kursliste
					KursListe klr = new KursListe();
					// Kurs k wird der Kursliste hinzugefuegt
					klr.addElement(k);
					// Student wird in der Platzkarte gesetzt
					pkNew.setStudent(platzkartenliste.elementAt(i).getStudent());
					// Kursliste wird der Platzkarte uebergeben
					pkNew.setKursliste(klr);
					// Die Platzkarte wird an die Platzkartenliste, die die
					// geloeschten Elemente enthaelt uebergeben
					pklRemoved.addElement(pkNew);
					// Removed parameter wird wieder zurueckgesetzt
					removed = false;

				}
			} else {
				// Die Platzkarte wird aus der Platzkartenliste geloescht
				platzkartenliste.removeElementAt(i);

			}
		}
		// Platzkartenliste wird uebergeben
		return pklRemoved;
	}

	/**
	 * Geht die Platzkartenliste durch und erstellt fuer mehrere Platzkarten eines Students eine Platzkarte mit einer passenden Kursliste
	 * Beispiel: Hat ein Student Anfangs zwei Platzkarten mit jeweils einem Kurs.
	 * Nachdem die Methode durchlaufen wurde hat der Student nur noch eine Platzkarte mit einer Kursliste. Die Kursliste enthaelt allerdings zwei Eintraege
	 * 
	 * @author Max Bogner
	 */
	public void makePlatzKartenUniqueByStudentNEW() {
		// loeschePlatzkartenMitKeinemKurs();
		// sortierte Platzkarten nach Studentenid
		List lUnique = platzkartenliste;
		PlatzKarte.setSortierKriterium("StudentenId");
		Collections.sort(lUnique, PlatzKarte.StudentenId);
		// Zuruecksetzen des Sortierkriteriums auf den Standard
		PlatzKarte.setSortierKriterium("AnzahlKurse");
		// Sortiertergebnis in die urspruengliche platzkartenliste schreiben
		platzkartenliste = ((Vector<PlatzKarte>) lUnique);
		// Initialisierung von benoetigten Variablen
		Vector<PlatzKarte> pkl = new Vector<PlatzKarte>();
		KursListe kl = new KursListe();
		int zaehler = 1;
		int mainpkl = 0;
		int studid = -9999;
		for (int i = 0; i < platzkartenliste.size() - 1; i++) {
			// Studentenmatrikelnummer des i-ten Druchlaufs
			int cnr = platzkartenliste.elementAt(i).getStudent()
					.getMatrikelnummer();
			// Studentenmatrikelnummer des i+1-ten Druchlaufs
			int nnr = platzkartenliste.elementAt(i + 1).getStudent()
					.getMatrikelnummer();
			// //Studentenmatrikelnummer des i-ten und des i+1-ten Druchlaufs
			// sind gleich
			if (cnr == nnr) {

				int snr = i;
				// Initialisierungsvariable
				boolean init = true;
				while (cnr == nnr && i < platzkartenliste.size() - 1) {
					// Anfangs müssen die Nummern initialisiert werden
					if (!init) {

						cnr = platzkartenliste.elementAt(i).getStudent()
								.getMatrikelnummer();
						nnr = platzkartenliste.elementAt(i + 1).getStudent()
								.getMatrikelnummer();

					}
					// Wenn matrikelnummern gleich sind
					if (cnr == nnr) {
						// Kursliste der Platzkarte ist groeßer als 0
						if (platzkartenliste.elementAt(i + 1).getKursliste()
								.getKursliste().size() > 0) {
							// hole den ersten Kurs der i+1-ten Platzkarte
							Kurs k2 = platzkartenliste.elementAt(i + 1)
									.getKursliste().getKursliste()
									.firstElement();
							// Kurs der Kursliste mit dem gleichen
							// Studentenmatrikelnummer hinzufuegen
							platzkartenliste.elementAt(snr).getKursliste()
									.addElement(k2);
						}
						// Platzkarte in die Platzkartenloeschliste uebergeben
						pkl.add(platzkartenliste.elementAt(i + 1));
						i++;
					}
					// Initialisierungsvariable setzen
					init = false;

				}

			}
			// alle in pkl enthaltenen Platzkarten aus der platzkartenliste
			// loeschen
			platzkartenliste.removeAll(pkl);

		}

	}

	/**
	 * Gibt die Anzahl der Platzkartenobjekte in der Platzkartenliste zurueck.
	 * 
	 * @author Kerstin Schulze Methoden fuer Ausgabe
	 * 
	 * @return (int) - Anzahl der Elemente in Vector als int
	 */
	// wird verwendet
	public int anzPlatzkarten() {
		return platzkartenliste.size();
	}

	/**
	 * Methode zum Bauen der Platzkartenliste je universitaet. Ergebnis zwei
	 * Platzkartenlisten, eine fuer Bamberg eine fuer Duisburg-Essen (Bestuecken
	 * der entsprechenden Variablen).
	 * 
	 * @author: Kerstin Schulze / Max Bogner
	 * 
	 * @param platzkartenliste
	 *            (PlatzKartenListe) zum Umformeln der Liste nach Universitaeten
	 * @return
	 */
	public Vector<PlatzKartenListe> PlatzkartenlisteNachUni() {
		// Initialisieren der PLatzkartenlisten fuer Bamberg und Duisburg
		PlatzKartenListe bamberg = new PlatzKartenListe();
		PlatzKartenListe duisburg = new PlatzKartenListe();
		Vector<PlatzKartenListe> pklList = new Vector<PlatzKartenListe>();
		// Durchlaufen von pklGesamt und umspeichern in die Vectoren Bamberg und
		// Duisburg
		for (int i = 0; i < platzkartenliste.size(); i++) {

			// Platzkarte an Index i
			PlatzKarte platzkarte = (PlatzKarte) platzkartenliste.elementAt(i);
			// .getPlatzkarteAtId(i);
			// Studentenobjekt der Platzkarte
			Student std = platzkarte.getStudent();

			System.out.println("PLatzkarte:-----"
					+ platzkarte.getStudent().getName() + "Uni: "
					+ platzkarte.getStudent().getUniversitaet());

			try {
				// if Abfrage: studiert Student in Bamberg oder Duisburg Essen,
				// dann
				// hinzufuegen zum jeweiligen Vector
				if (std.getUniversitaet().equals("Bamberg")) {
					bamberg.addElement(platzkarte);
				} else if (std.getUniversitaet().equals("Duisburg-Essen")) {
					duisburg.addElement(platzkarte);
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (bamberg.getPlatzkartenliste().size() > 0) {
			pklList.add(bamberg);
		}
		if (duisburg.getPlatzkartenliste().size() > 0) {
			pklList.add(duisburg);
		}
		return pklList;
	}

}
